using System;
using System.Collections.Generic;
using System.IO;
using SCore.Util;
using UnityEngine;

namespace Function.HotUpdate
{
    public enum HotUpdateErrorType
    {
        None = 0,
        FetchLighthouse = 1, // LightHouse 访问失败
        LocalBundleCacheFair = 2, //本地bundle换成文件访问失败,
        CheckForCatalogUpdateFair = 3, //检测Addressable Catalog Fair
        UpdateCatalogsFair = 4, //更新Addressable Catalog Fair
        DownloadFair = 5, //下载资源失败
        NotReachable = 6, //没有网络连接
        FetchLighthouse_InitializeAsync = 7, //初始化Addressable失败
        NeedStoreDown = 16, //需要去商店下载
        NeedStopGame = 17, //热更新dll 需要重启游戏
    }

    public class HotContext
    {
        public string _assetsVersion = "AssetsVersion.txt"; //cache 里的 缓存文件

        public int _downLoadCount = 3; //下载重试次数
        public string _addressableURL; //addressable 配置的地址
        public string _assettUrl; //addressable asset地址
        public string _channel; //渠道
        public Lighthouse _lighthouse; //lighthouse
        public string _injectEnv;

        public Version _bootVersion; //当前打包的时候的版本号
        public Version _version; //StreamingAsset版本号 与应用版本号一致 更新结束后的版本号会存到这个里面
        public Version _remoteVersion; //远程资源版本号
        public string _cacheVersionStr; //更新检测时本地缓存的版本号字符串

        public List<object> _updateKeys = new(); //更新key
        public HotStep _step; //更新节点
        private NetworkReachability _lastNet; //网络状态

        public bool _needUpdate; //是否需要热更
        public bool _updateDll; //是否热更新dll
        public static bool _firstHotFinish = false; //是否已经热更新过

        public Version BeforeVersion
        {
            get
            {
                if (string.IsNullOrEmpty(_cacheVersionStr))
                {
                    return _version;
                }
                else
                {
                    return new Version(_cacheVersionStr);
                }
            }
        }

        public string GetLightHouseURL()
        {
            //http://10.0.84.152:8081/xnext/Android
            $"[hotupdate] will GetLightHouseURL:{_addressableURL} {_channel}".Log();
            var url = $"{_addressableURL}/lighthouse_{UnityUtils.GetBuildTargetName().ToLower()}.json";
            url = HotUpdateUtils.WrapUrlWithTimePostfix(url);
            $"[hotupdate] LightHouseURL:{url}".Log();
#if UNITY_EDITOR
            url = "http://10.0.84.152:8081/xnext/android/lighthouse_android.json";
            $"[hotupdate] using mock url for editor: {url}".Log();
#endif
            return url;
        }

        public string GetRemoteResVersion()
        {
            if (_lighthouse != null)
            {
                return _lighthouse.GetRemoteResVersion(_injectEnv);
            }
            else
            {
                return "0.0.0";
            }
        }


        // 选bin和res里二者更大的版本号
        public Version GetGreaterOfResAndBin()
        {
            if (!string.IsNullOrEmpty(_injectEnv))
            {
                var resVersion = GetRemoteResVersion();
                var res = new Version(resVersion);
                return res;
            }
            else
            {
                var resVersion = GetRemoteResVersion();
                var res = new Version(resVersion);
                var bin = _bootVersion;
                if (res.CompareTo(bin) > 0)
                {
                    return res;
                }
                else
                {
                    return bin;
                }
            }
        }

        public HotContext()
        {
            _lastNet = Application.internetReachability;
            _cacheVersionStr = GetCacheVersion();
        }

        public void Error(string des, string error, int id)
        {
            $"[HotUpdate]:{des} {error}".Error();
            HotManager.Instance._errorPop?.Invoke(id);
        }

        public void Info(string des, string error)
        {
            $"[HotUpdate]:{des} {error}".Error();
        }

        public void Update()
        {
            if (Application.internetReachability != _lastNet)
            {
                switch (Application.internetReachability)
                {
                    case NetworkReachability.NotReachable:
                        if (_step != null) _step.StopNet();
                        HotManager.Instance._disconnectNet?.Invoke();
                        Error("network is closed", "network connect fair", (int)HotUpdateErrorType.NotReachable);
                        break;
                    case NetworkReachability.ReachableViaCarrierDataNetwork:
                    //切换4G TODO
                    case NetworkReachability.ReachableViaLocalAreaNetwork:
                        HotManager.Instance._reconnectNet?.Invoke();
                        //if (_step != null) _step.ResNet();
                        break;
                    default:
                        break;
                }

                _lastNet = Application.internetReachability;
            }
        }

        private string GetCacheVersion()
        {
            string path = UnityUtils.GetCacheDirectory() + "/" + _assetsVersion;
            if (!File.Exists(path))
                return string.Empty;
            return File.ReadAllText(path);
        }
    }
}